/**
 * 
 */
package com.vchello.util;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.methods.GetMethod;

/**
 * @author power
 * @time 2015年11月25日上午10:57:04
 */
@SuppressWarnings("static-access")
public class SmsUtil {
	
	/**
	 * 移通网络企业短消息平台
	 * Hex编码字符组
	 */
	private static final char[] DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };


	private static ReadPropertyUtil readProperty = ReadPropertyUtil.getInstance();
	private static String url = "";
	private static String account = "";
	private static String password = "";

	private static String noticeAccount = "";
	private static String noticePassword = "";
	
	private static String ytUrl = "";
	private static String ytAccount = "";
	private static String ytPassword = "";

	static {
		url = readProperty.getProperty("url", "http://222.73.117.158/msg/index.jsp");
		account = readProperty.getProperty("account", "VChello");
		password = readProperty.getProperty("password", "VChello8888");
		noticeAccount = readProperty.getProperty("noticeAccount", "VChello1");
		noticePassword = readProperty.getProperty("noticePassword", "VChello18888");
		
		ytUrl = readProperty.getProperty("ytUrl", "http://esms100.10690007.net/sms/mt");
		ytAccount = readProperty.getProperty("ytAccount", "3308");
		ytPassword = readProperty.getProperty("ytPassword", "aY5NLf3g");
	}

	/**
	 * 验证码 单发
	 * 
	 * @param mobile
	 *            手机号码，多个号码使用","分割
	 * @param msg
	 *            短信内容
	 * @param needstatus
	 *            是否需要状态报告，需要true，不需要false
	 * @return 返回值定义参见HTTP协议文档
	 * @throws Exception
	 */
	public static String send(String mobile, String msg, boolean needstatus, String product, String extno)
			throws Exception {
		HttpClient client = new HttpClient();
		GetMethod method = new GetMethod();
		try {
			URI base = new URI(url, false);
			method.setURI(new URI(base, "HttpSendSM", false));
			method.setQueryString(new NameValuePair[] { new NameValuePair("account", account),
					new NameValuePair("pswd", password), new NameValuePair("mobile", mobile),
					new NameValuePair("needstatus", String.valueOf(needstatus)), new NameValuePair("msg", msg),
					new NameValuePair("product", product), new NameValuePair("extno", extno), });
			int result = client.executeMethod(method);
			if (result == HttpStatus.SC_OK) {
				InputStream in = method.getResponseBodyAsStream();
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
				byte[] buffer = new byte[1024];
				int len = 0;
				while ((len = in.read(buffer)) != -1) {
					baos.write(buffer, 0, len);
				}
				return URLDecoder.decode(baos.toString(), "UTF-8");
			} else {
				throw new Exception("HTTP ERROR Status: " + method.getStatusCode() + ":" + method.getStatusText());
			}
		} finally {
			method.releaseConnection();
		}

	}

	/**
	 * 验证码 群发
	 * 
	 * @param mobile
	 *            手机号码，多个号码使用","分割
	 * @param msg
	 *            短信内容
	 * @param needstatus
	 *            是否需要状态报告，需要true，不需要false
	 * @return 返回值定义参见HTTP协议文档
	 * @throws Exception
	 */
	public static String batchSend(String mobile, String msg, boolean needstatus, String product, String extno)
			throws Exception {
		HttpClient client = new HttpClient();
		GetMethod method = new GetMethod();
		try {
			URI base = new URI(url, false);
			method.setURI(new URI(base, "HttpBatchSendSM", false));
			method.setQueryString(new NameValuePair[] { new NameValuePair("account", account),
					new NameValuePair("pswd", password), new NameValuePair("mobile", mobile),
					new NameValuePair("needstatus", String.valueOf(needstatus)), new NameValuePair("msg", msg),
					new NameValuePair("product", product), new NameValuePair("extno", extno), });
			int result = client.executeMethod(method);
			if (result == HttpStatus.SC_OK) {
				InputStream in = method.getResponseBodyAsStream();
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
				byte[] buffer = new byte[1024];
				int len = 0;
				while ((len = in.read(buffer)) != -1) {
					baos.write(buffer, 0, len);
				}
				return URLDecoder.decode(baos.toString(), "UTF-8");
			} else {
				throw new Exception("HTTP ERROR Status: " + method.getStatusCode() + ":" + method.getStatusText());
			}
		} finally {
			method.releaseConnection();
		}

	}

	/**
	 * 发通知信息
	 * 
	 * @param mobile
	 * @param msg
	 * @param needstatus
	 * @param product
	 * @param extno
	 * @return
	 * @throws Exception
	 */
	public static String sendNoticeSms(String mobile, String msg, boolean needstatus, String product, String extno)
			throws Exception {
		HttpClient client = new HttpClient();
		GetMethod method = new GetMethod();
		try {
			URI base = new URI(url, false);
			method.setURI(new URI(base, "HttpBatchSendSM", false));
			method.setQueryString(new NameValuePair[] { new NameValuePair("account", noticeAccount),
					new NameValuePair("pswd", noticePassword), new NameValuePair("mobile", mobile),
					new NameValuePair("needstatus", String.valueOf(needstatus)), new NameValuePair("msg", msg),
					new NameValuePair("product", product), new NameValuePair("extno", extno), });
			int result = client.executeMethod(method);
			if (result == HttpStatus.SC_OK) {
				InputStream in = method.getResponseBodyAsStream();
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
				byte[] buffer = new byte[1024];
				int len = 0;
				while ((len = in.read(buffer)) != -1) {
					baos.write(buffer, 0, len);
				}
				return URLDecoder.decode(baos.toString(), "UTF-8");
			} else {
				throw new Exception("HTTP ERROR Status: " + method.getStatusCode() + ":" + method.getStatusText());
			}
		} finally {
			method.releaseConnection();
		}
	}

	/**
	 * 移通网络企业短消息平台
	 * 
	 * @return
	 */
	public static String singleMt(String phone, String content) {
		// 操作命令、SP编号、SP密码，必填参数
		String command = "MT_REQUEST";
		// sp服务代码，可选参数，默认为 00
		String spsc = "00";
		// 源号码，可选参数
		String sa = "10657109053657";
		// 目标号码，必填参数
		// String da = "8618665690991";
		phone = "86" + phone;
		// 下行内容以及编码格式，必填参数
		int dc = 15;
		String sm = encodeHexStr(dc, content);// 下行内容进行Hex编码，此处dc设为15，即使用GBK编码格式

		// 组成url字符串
		String smsUrl = ytUrl + "?command=" + command + "&spid=" + ytAccount + "&sppassword=" + ytPassword + "&spsc="
				+ spsc + "&sa=" + sa + "&da=" + phone + "&sm=" + sm + "&dc=" + dc;

		// 发送http请求，并接收http响应
		String resStr = doGetRequest(smsUrl.toString());
		System.out.println(resStr);
		Map<String, String> map = parseResStr(resStr);
		System.out.println(map.get("command"));
		System.out.println(map.get("spid"));
		System.out.println(map.get("mtmsgid"));
		System.out.println(map.get("mtstat"));
		System.out.println(map.get("mterrcode"));
		return resStr;

	}

	/**
	 * 发送http GET请求，并返回http响应字符串
	 * 
	 * @param urlstr
	 *            完整的请求url字符串
	 * @return
	 */
	public static String doGetRequest(String urlstr) {
		String res = null;
		try {
			URL url = new URL(urlstr);
			HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
			httpConn.setRequestMethod("GET");
			httpConn.setRequestProperty("Content-Type", "text/html; charset=GB2312");
			System.setProperty("sun.net.client.defaultConnectTimeout", "5000");// jdk1.4换成这个,连接超时
			System.setProperty("sun.net.client.defaultReadTimeout", "10000"); // jdk1.4换成这个,读操作超时
			// httpConn.setConnectTimeout(5000);//jdk 1.5换成这个,连接超时
			// httpConn.setReadTimeout(10000);//jdk 1.5换成这个,读操作超时
			httpConn.setDoInput(true);
			int rescode = httpConn.getResponseCode();
			if (rescode == 200) {
				BufferedReader bfw = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
				res = bfw.readLine();
			} else {
				res = "Http request error code :" + rescode;
			}
		} catch (Exception e) {
			System.out.println(e.toString());
		}
		return res;
	}

	/**
	 * 发送http POST请求，并返回http响应字符串
	 * 
	 * @param urlstr
	 *            完整的请求url字符串
	 * @return
	 */
	public static String doPostRequest(String urlstr, String dasms) {
		String res = null;
		try {
			URL url = new URL(urlstr);
			HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
			httpConn.setDoOutput(true);
			httpConn.setDoInput(true);
			httpConn.setRequestMethod("POST");
			httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=ISO-8859-1");
			OutputStream outputstream = httpConn.getOutputStream();
			outputstream.write(("dasm=" + dasms).getBytes());
			outputstream.flush();

			System.setProperty("sun.net.client.defaultConnectTimeout", "5000");// jdk1.4换成这个,连接超时
			System.setProperty("sun.net.client.defaultReadTimeout", "10000"); // jdk1.4换成这个,读操作超时
			// httpConn.setConnectTimeout(5000);//jdk 1.5换成这个,连接超时
			// httpConn.setReadTimeout(5000);//jdk 1.5换成这个,读操作超时

			int rescode = httpConn.getResponseCode();
			if (rescode == 200) {
				BufferedReader bfw = new BufferedReader(new InputStreamReader(httpConn.getInputStream()));
				res = bfw.readLine();
			} else {
				res = "Http request error code :" + rescode;
			}
		} catch (Exception e) {
			System.out.println(e.toString());
		}
		return res;
	}

	/**
	 * 将普通字符串转换成Hex编码字符串
	 * 
	 * @param dataCoding
	 *            编码格式，15表示GBK编码，8表示UnicodeBigUnmarked编码，0表示ISO8859-1编码
	 * @param realStr
	 *            普通字符串
	 * @return Hex编码字符串
	 */
	public static String encodeHexStr(int dataCoding, String realStr) {
		String hexStr = null;

		if (realStr != null) {
			byte[] data = null;
			try {
				if (dataCoding == 15) {
					data = realStr.getBytes("GBK");
				} else if ((dataCoding & 0x0C) == 0x08) {
					data = realStr.getBytes("UnicodeBigUnmarked");
				} else {
					data = realStr.getBytes("ISO8859-1");
				}
			} catch (UnsupportedEncodingException e) {
				System.out.println(e.toString());
			}

			if (data != null) {
				int len = data.length;
				char[] out = new char[len << 1];
				// two characters form the hex value.
				for (int i = 0, j = 0; i < len; i++) {
					out[j++] = DIGITS[(0xF0 & data[i]) >>> 4];
					out[j++] = DIGITS[0x0F & data[i]];
				}
				hexStr = new String(out);
			}
		}
		return hexStr;
	}

	/**
	 * 将Hex编码字符串还原成普通字符串
	 * 
	 * @param dataCoding
	 *            反编码格式，15表示GBK编码，8表示UnicodeBigUnmarked编码，0表示ISO8859-1编码
	 * @param hexStr
	 *            Hex编码字符串
	 * @return 普通字符串
	 */
	public static String decodeHexStr(int dataCoding, String hexStr) {
		String realStr = null;

		if (hexStr != null) {
			char[] data = hexStr.toCharArray();

			int len = data.length;

			if ((len & 0x01) != 0) {
				throw new RuntimeException("Odd number of characters.");
			}

			byte[] out = new byte[len >> 1];

			// two characters form the hex value.
			for (int i = 0, j = 0; j < len; i++) {
				int f = Character.digit(data[j], 16) << 4;
				if (f == -1) {
					throw new RuntimeException("Illegal hexadecimal charcter " + data[j] + " at index " + j);
				}
				j++;
				f = f | Character.digit(data[j], 16);
				if (f == -1) {
					throw new RuntimeException("Illegal hexadecimal charcter " + data[j] + " at index " + j);
				}
				j++;
				out[i] = (byte) (f & 0xFF);
			}
			try {
				if (dataCoding == 15) {
					realStr = new String(out, "GBK");
				} else if ((dataCoding & 0x0C) == 0x08) {
					realStr = new String(out, "UnicodeBigUnmarked");
				} else {
					realStr = new String(out, "ISO8859-1");
				}
			} catch (UnsupportedEncodingException e) {
				System.out.println(e.toString());
			}
		}

		return realStr;
	}

	/**
	 * 将 短信下行 请求响应字符串解析到一个HashMap中
	 * 
	 * @param resStr
	 * @return
	 */
	public static Map<String, String> parseResStr(String resStr) {
		Map<String, String> pp = new HashMap<String, String>();
		try {
			String[] ps = resStr.split("&");
			for (int i = 0; i < ps.length; i++) {
				int ix = ps[i].indexOf("=");
				if (ix != -1) {
					pp.put(ps[i].substring(0, ix), ps[i].substring(ix + 1));
				}
			}
		} catch (Exception e) {
			System.out.println(e.toString());
		}
		return pp;
	}

}
